package com.thti.mecool.client.service;

import java.io.IOException;
import java.io.InputStream;
import java.io.StringWriter;
import java.io.Writer;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.ConnectException;
import java.net.SocketException;
import java.net.SocketTimeoutException;
import java.util.HashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import org.apache.http.conn.ConnectTimeoutException;
import org.apache.http.conn.HttpHostConnectException;
import org.codehaus.jackson.JsonGenerationException;
import org.codehaus.jackson.JsonParseException;
import org.codehaus.jackson.map.JsonMappingException;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.map.DeserializationConfig.Feature;
import org.json.JSONException;
import org.json.JSONObject;

import android.os.Message;

import com.thti.mecool.client.base.BaseActivity;
import com.thti.mecool.client.command.ICommand;
import com.thti.mecool.client.command.ManageCommand;
import com.thti.mecool.client.util.NetTool;
import com.thti.mecool.client.util.Util;


/**
 * 
 * @author weiguo.ren
 * 
 */


public class ThtiService {
	private static String commandId=null;
	private static ExecutorService mExecutorService = Executors
			.newFixedThreadPool(5);

	static HashMap<String, Long> timeMap = new HashMap<String, Long>();
	
	

	public static void sendProtocol(String protocol, Object o) {
		commandId=protocol;
		try {
			StringBuffer params = new StringBuffer();
			
               
				if (o != null) {
					if(protocol.contains("plan_addplan")){
						commandId="plan_addplan";
						params.append(o);
					}else if(protocol.contains("sellinto_editsellinto")){
						params.append(forJosn(o));
					}else{
				    	params.append(copy(o));
					}
				}
			
			sendProtocol(params.toString(), protocol);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	private static void sendProtocol(final String params,
			final String protocol) {
		mExecutorService.execute(new Runnable() {
			@SuppressWarnings({ "unchecked", "deprecation" })
			@Override
			public void run() {
				byte[] bytes = null;
				try { 
					Util.print("[-------url-----]: "+Protocol.getURL+protocol.replace("_", "/")+"?"+params);
					InputStream in = null;
					if(protocol.contains("plan_addplan")||protocol.equals("sellinto_editsellinto")){
						System.out.println("net post json!");
						in = NetTool.POSTJson(Protocol.getURL+protocol.replace("_", "/"), params);
					}else{
						in = NetTool.POST(Protocol.getURL+protocol.replace("_", "/")+"?", params);
					}
					if (null != in) {
						bytes=NetTool.read(in);
						Util.print("[-------Result-----]: "+new String(bytes));
						JSONObject jsons = new JSONObject(new String(bytes));
						String protocolID = jsons.get("command").toString();
						String id = jsons.get("result").toString();		
						if(Integer.parseInt(id) == 0){
							Util.print("服务器返回错误");
							Message msg = new Message();
							BaseActivity.serverErrorHandler.sendMessage(msg);
							return;
						}
						if(!ManageCommand.commads.containsKey(protocolID)){
							Util.print("Command [" + protocolID
									+ "] Not Found ...");
							return;
						}else{
							ICommand command = ManageCommand.commads
									.get(protocolID);
							Util.print(jsons.get("body").toString());
							Util.print(command.getCommandClass());
							ObjectMapper mapper = new ObjectMapper();
							/**忽略新字段*/
							mapper.getDeserializationConfig().set(Feature.FAIL_ON_UNKNOWN_PROPERTIES, false);
							Object obj=mapper.readValue(jsons.get("body").toString(),command.getCommandClass());
							command.doCommand(obj);
						}
					}else{
						exception("上传失败！");
					}
				}catch(ConnectTimeoutException cte){
					exception("连接服务器超时！");
				}catch(HttpHostConnectException hhce){
					exception("连接服务器异常！");
				}catch(ConnectException cone){
					exception("连接服务器异常！");
					cone.printStackTrace();
				}catch(SocketTimeoutException ste){
					exception("连接服务器超时！");
					ste.printStackTrace();
				}catch(SocketException se){
					exception("连接服务器异常！");
					se.printStackTrace();
				}
				catch (Exception e) {
					exception("未知错误！");
					e.printStackTrace();
				}
			}
		});
	}
	@SuppressWarnings("unchecked")
	public static void exception(String exceptionName){
		String json="{\"command\":\""+commandId+"\",\"result\":\"1\",\"body\":{\"status\":\"0\",\"msg\":{\"content\":\""+exceptionName+"\"}}}";
		JSONObject jsons = null;
		try {
			jsons = new JSONObject(json);
		} catch (JSONException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		ObjectMapper mapper = new ObjectMapper();  
		ICommand command = ManageCommand.commads
				.get(commandId);
		try {
			Object obj=mapper.readValue(jsons.get("body").toString(),command.getCommandClass());
			command.doCommand(obj);
		} catch (JsonParseException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (JsonMappingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (JSONException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	public static String forJosn(Object obj){
		ObjectMapper mapper = new ObjectMapper();  
		Writer strWriter = new StringWriter();
		try {
			mapper.writeValue(strWriter, obj);
		} catch (JsonGenerationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (JsonMappingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return strWriter.toString();
	}
	
	public static String copy(Object obj) throws IllegalArgumentException,
			SecurityException, InstantiationException, IllegalAccessException,
			InvocationTargetException, NoSuchMethodException {
		Class<?> classType = obj.getClass();
		Object objectCopy = classType.getConstructor(new Class[] {})
				.newInstance(new Object[] {});
		Field[] fields = classType.getDeclaredFields();
		StringBuffer sb = new StringBuffer();
		for (int i = 0; i < fields.length; i++) {
			Field field = fields[i];
			String fieldName = field.getName();
			if (fieldName.equals("serialVersionUID")) {
				continue;
			}
			String stringLetter = fieldName.substring(0, 1).toUpperCase();
			String getName = "get" + stringLetter + fieldName.substring(1);
			String setName = "set" + stringLetter + fieldName.substring(1);
			Method getMethod = classType.getMethod(getName, new Class[] {});
			Method setMethod = classType.getMethod(setName,
					new Class[] { field.getType() });
			Object value = getMethod.invoke(obj, new Object[] {});
			if(fieldName.equals("page") || fieldName.equals("size")){
				sb.append("&page." + fieldName + "=" + value);
			}else{
			sb.append("&" + fieldName + "=" + value);
			}
			setMethod.invoke(objectCopy, new Object[] { value });
		}
		return sb.toString();
	}
}
